<template>
  <!--自定义流程设计组件-->
  <div class="flowpath">
    <div class="zoom">
      <div class="zoom-out" :class="{'disabled':zoomSize==50}" @click="setZoom(0)"></div>
      <span>{{zoomSize}}%</span>
      <div class="zoom-in" :class="{'disabled':zoomSize==150}" @click="setZoom(1)"></div>
    </div>
    <div class="panl" :style="'transform: scale('+zoomSize/100+'); transform-origin: 50% 0px 0px;'">
      <designer :node.sync="node" @opend="openDrawer" :getConditionsText="getConditionsText"></designer>
      <div class="end-node">
        <div class="end-node-circle"></div>
        <div class="end-node-text">流程结束</div>
      </div>
    </div>
    <!--条件设置面板-->
    <el-drawer class="drawer" :visible.sync="drawerCondition" direction="rtl">
      <div slot="title">{{drawerNode.name}}</div>
      <div class="content">
        <div class="tip">当审批单同时满足以下条件时进入此流程</div>
        <div class="groupList">
          <template v-for="(condition,conditionIndex) in conditionList">
            <div class="group" :key="conditionIndex">
              <div class="header">
                <span class="title">条件组{{conditionIndex+1}}</span>
                <i v-if="conditionList.length>1" @click="conditionDelete(conditionIndex)" class="el-icon-delete"></i>
              </div>
              <div class="condition">
                <div class="list">
                  <div class="item" v-for="(item,index) in condition" :key="index">
                    <div class="name">
                      {{getParamKey(item.paramKey).props.label}}
                    </div>
                    <div class="type">
                      <span v-if="getParamKey(item.paramKey).componentName !== 'NumberField'">等于</span>
                      <el-select v-else v-model="item.type" placeholder="请选择">
                        <el-option v-for="item in conditionType" :key="item.value" :label="item.label" :value="item.value">
                        </el-option>
                      </el-select>
                    </div>
                    <div class="value" :class="{'betweenness':item.type=='xrange'}">
                      <el-input v-model="item.paramValue" placeholder="请输入"></el-input>
                      <span v-if="item.type=='xrange'"> - </span>
                      <el-input v-if="item.type=='xrange'" v-model="item.paramValue2" placeholder="请输入"></el-input>
                    </div>
                    <div class="delete">
                      <i @click="conditionListDelete(index,condition)" class="el-icon-delete"></i>
                    </div>
                  </div>
                </div>
                <div class="btn">
                  <el-button size="mini" plain type="primary" icon="el-icon-plus" @click="openCondition(condition,conditionIndex)">添加条件</el-button>
                  还有{{getCacheWidgetList(condition).length}}个可用条件
                </div>
              </div>
            </div>
            <div v-if="conditionList.length-1>conditionIndex" :key="'divider_'+conditionIndex" class="divider">或</div>
          </template>
          <div class="add">
            <el-button size="small" type="primary" icon="el-icon-plus" @click="addConditionList()">添加条件组</el-button>
          </div>
        </div>
      </div>
      <div class="footer">
        <el-button size="small" type="info" @click="drawerCondition = false">取 消</el-button>
        <el-button size="small" type="success" @click="saveConditionDrawer()">保 存</el-button>
      </div>
    </el-drawer>
    <!--条件选择面板-->
    <el-dialog title="选择条件" :visible.sync="dialogCondition" width="600px">
      <div style="padding:10px 0">请选择用来区分审批流程的条件字段 ，已选{{checkCondition.length}}个</div>
      <div>
        <el-checkbox-group v-model="checkCondition">
          <el-checkbox :label="item.value" v-for="(item,index) in cacheWidgetList" :key="index">{{item.label}}</el-checkbox>
        </el-checkbox-group>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogCondition = false">取 消</el-button>
        <el-button type="primary" @click="saveCondition()">确 定</el-button>
      </span>
    </el-dialog>
    <!--审批设置面板-->
    <el-drawer class="drawer" :visible.sync="drawerApprove" direction="rtl">
      <div slot="title">{{drawerNode.name}}</div>
      <div class="approve">
        <div class="modelType">
          <div class="modelType-title">
            审批类型
          </div>
          <div class="modelType-content">
            <el-radio-group v-model="propertyApprove.type">
              <el-radio :label="item.value" v-for="(item,index) in approveType" :key="index">{{item.label}}</el-radio>
            </el-radio-group>
          </div>
        </div>
        <template v-if="propertyApprove.type == 'manual'">
          <div class="modelType">
            <div class="modelType-title">
              请选择该节点审批人
            </div>
            <div class="modelType-content">
              <el-radio-group class="shu" v-model="propertyApprove.operaterType">
                <el-radio :label="item.value" v-for="(item,index) in approveOperaterType" :key="index">{{item.label}}</el-radio>
              </el-radio-group>
            </div>
          </div>
          <div class="modelType" v-if="propertyApprove.operaterType">
            <div class="modelType-title">
              {{getApproveOperaterTypeTitle()}}
            </div>
            <div class="modelType-content">
              <el-select v-model="propertyApprove.operaters" clearable placeholder="请选择">
                <el-option v-for="item in [{
          label: '测试数据',
          value: 'default'
        }]" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </div>
          </div>
          <div class="modelType">
            <div class="modelType-title">
              多人审批时采用的审批方式
            </div>
            <div class="modelType-content">
              <el-radio-group class="shu" v-model="propertyApprove.mode">
                <el-radio :label="item.value" v-for="(item,index) in approveModeType" :key="index">{{item.label}}</el-radio>
              </el-radio-group>
            </div>
          </div>
          <div class="modelType">
            <div class="modelType-title">
              审批人为空时
            </div>
            <div class="modelType-content">
              <el-radio-group class="shu" v-model="propertyApprove.emptyOperater">
                <el-radio :label="item.value" v-for="(item,index) in approveEmptyOperaterType" :key="index">{{item.label}}</el-radio>
              </el-radio-group>
            </div>
          </div>
          <div class="modelType">
            <div class="modelType-title">
              抄送人
            </div>
            <div class="modelType-content">
              <div class="userlist">
                <el-button size="small" type="success" @click="addUser()" icon="el-icon-plus">添加</el-button>
              </div>
            </div>
          </div>
        </template>
      </div>
      <div class="footer">
        <el-button size="small" type="info" @click="drawerApprove = false">取 消</el-button>
        <el-button size="small" type="success" @click="saveApproveDrawer()">保 存</el-button>
      </div>
    </el-drawer>
  </div>
</template>

<script>
import designer from './workflow/designer.vue'
export default {
  name: 'approveFlowPath',
  components: { designer },
  props: ['widgetList'],
  watch: {
    node: {
      handler (newVal, oldVal) {
        this.$emit('changed', newVal)
      },
      deep: true,
      immediate: true
    }
  },
  data () {
    return {
      zoomSize: 100,
      drawerCondition: false,
      dialogCondition: false,
      checkCondition: [],
      cacheWidgetList: [],
      conditionList: [[]],
      conditionIndex: 0,
      conditionType: [
        {
          label: '小于',
          value: 'lowerBound',
          labelText: ' < '
        },
        {
          label: '大于',
          value: 'upperBound',
          labelText: ' > '
        },
        {
          label: '小于等于',
          value: 'lowerBoundEqual',
          labelText: ' <= '
        },
        {
          label: '等于',
          value: 'boundEqual',
          labelText: ' = '
        },
        {
          label: '大于等于',
          value: 'upperBoundEqual',
          labelText: ' >= '
        },
        {
          label: '介于（两个数之间）',
          value: 'xrange',
          labelText: ''
        }
      ],
      drawerApprove: false,
      approveType: [
        {
          label: '人工审批',
          value: 'manual'
        },
        {
          label: '自动通过',
          value: 'autoAgree'
        },
        {
          label: '自动拒绝',
          value: 'autoReject'
        }
      ],
      approveOperaterType: [
        {
          label: '指定成员',
          value: 'target'
        },
        {
          label: '发起人',
          value: 'sender'
        },
        {
          label: '角色',
          value: 'role'
        },
        {
          label: '直属或连续多级主管',
          value: 'manager'
        }
      ],
      approveModeType: [
        {
          label: '依次审批(按顺序同意或拒绝)',
          value: 'step'
        },
        {
          label: '会签(需要所有审批人都同意才可以通过)',
          value: 'and'
        },
        {
          label: '或签(其中一名审批人同意或拒绝即可)',
          value: 'or'
        }
      ],
      approveEmptyOperaterType: [
        {
          label: '自动通过',
          value: 'autoAgree'
        },
        {
          label: '自动转交管理员',
          value: 'admin'
        },
        {
          label: '指定审批人',
          value: 'target'
        },
        {
          label: '不许发起审批申请',
          value: 'failed'
        }
      ],
      propertyApprove: {
        type: '',
        operaterType: ''
      },
      node: {
        name: '发起人', // 节点名称
        type: 'start', // 节点类型 start：发起人 approval：审批人 condition：条件 route：路由
        placeholder: '请选择发起人', // 默认显示
        propertys: {},
        nodeId: 'start'
      },
      drawerNode: {} // 当前设置操作的节点
    }
  },
  methods: {
    getApproveOperaterTypeTitle () {
      const _arr = this.approveOperaterType.find(
        (item) => item.value === this.propertyApprove.operaterType
      )
      return _arr ? _arr.label : ''
    },
    setZoom (type) {
      if (!type) {
        if (this.zoomSize === 50) {
          return
        }
        this.zoomSize -= 10
      } else {
        if (this.zoomSize === 150) {
          return
        }
        this.zoomSize += 10
      }
    },
    addConditionList () {
      this.conditionList.push([])
    },
    saveCondition () {
      if (!this.checkCondition.length) {
        this.$alert('请选择条件', '温馨提示')
        return
      }
      this.checkCondition.forEach((item) => {
        this.conditionList[this.conditionIndex].push({
          paramKey: item,
          type:
            this.getParamKey(item).componentName !== 'NumberField'
              ? 'boundEqual'
              : '',
          paramValue: '',
          paramValue2: ''
        })
      })
      this.dialogCondition = false
    },
    getCacheWidgetList (list) {
      const _cacheWidgetList = []
      // 循环，排除存在的，去掉不能选的，组成新的集合
      this.widgetList.forEach((item) => {
        if (item.flowpath && item.props.required) {
          let _add = true
          list.forEach((row) => {
            // 如果存在
            if (row.paramKey === item.props.name) {
              _add = false
            }
          })
          if (_add) {
            _cacheWidgetList.push({
              label: item.props.label,
              value: item.props.name
            })
          }
        }
      })
      return _cacheWidgetList
    },
    openCondition (list, index) {
      this.conditionIndex = index
      this.cacheWidgetList = this.getCacheWidgetList(list)
      if (!this.cacheWidgetList.length) {
        this.$alert('暂无可选条件，请在表单设计中添加', '温馨提示')
        return
      }
      this.checkCondition = []
      this.dialogCondition = true
    },
    // 删除
    conditionDelete (i) {
      this.conditionList.splice(i, 1)
    },
    conditionListDelete (i, list) {
      list.splice(i, 1)
    },
    // 根据条件KEY，获取名称
    getParamKey (paramKey) {
      const _arr = this.widgetList.filter((item) => item.props.name === paramKey)
      return _arr.length ? _arr[0] : { props: { label: '组件不存在' } }
    },
    // 打开 n:当前节点
    openDrawer (n) {
      this.drawerNode = n
      // 如果点击的是条件节点
      if (n.type === 'condition') {
        // 深复制
        this.conditionList = JSON.parse(JSON.stringify(n.conditions))
        this.drawerCondition = true
        return
      }
      // 深复制
      this.propertyApprove = JSON.parse(JSON.stringify(n.propertys))
      this.drawerApprove = true
      // 否则打开审批人设置
    },
    // 转义运算符
    getConditionType (t) {
      const _arr = this.conditionType.filter((item) => item.value === t)
      return _arr.length ? _arr[0].labelText : ''
    },
    // 转义中文
    getConditionsText (list) {
      let _text = ''
      list.forEach((x, o) => {
        if (o !== 0) {
          _text += '<br/>或<br/>'
        }
        x.forEach((y, i) => {
          if (i !== 0) {
            _text += ' && '
          }
          if (y.type === 'xrange') {
            _text +=
              y.paramValue +
              ' >= ' +
              this.getParamKey(y.paramKey).props.label +
              ' <=' +
              y.paramValue2
            return
          }
          _text +=
            this.getParamKey(y.paramKey).props.label +
            this.getConditionType(y.type) +
            y.paramValue
        })
      })
      return _text
    },
    // 添加抄送人
    addUser () {
      alert('没定数据格式，暂不处理')
    },
    // 审批保存
    saveApproveDrawer () {
      if (this.propertyApprove.type === 'manual' &&
        this.propertyApprove.operaterType &&
        !this.propertyApprove.operaters
      ) {
        this.$alert('请选择' + this.getApproveOperaterTypeTitle(), '温馨提示')
        return
      }
      this.drawerNode.propertys = this.propertyApprove
      this.drawerApprove = false
    },
    // 条件保存
    saveConditionDrawer () {
      // 验证非空
      let _msg = ''
      const _getMsg = (i, paramKey) => {
        return (
          '条件组' +
          (i + 1) +
          '：【' +
          this.getParamKey(paramKey).props.label +
          '】'
        )
      }
      this.conditionList.forEach((x, i) => {
        if (!_msg) {
          x.forEach((y) => {
            if (!y.type && !_msg) {
              _msg = _getMsg(i, y.paramKey) + '未设置条件'
            }
            if (!y.paramValue && !_msg) {
              _msg = _getMsg(i, y.paramKey) + '未设置值'
            }
            if (y.type === 'xrange' && !y.paramValue2 && !_msg) {
              _msg = _getMsg(i, y.paramKey) + '未设置值'
            }
          })
        }
      })
      if (_msg) {
        this.$alert(_msg, '温馨提示')
        return
      }
      this.drawerNode.conditions = this.conditionList
      this.drawerCondition = false
    }
  }
}
</script>

<style lang="scss" scoped>
.flowpath {
  width: 100%;
  background-color: #f5f5f7;
  height: calc(100vh - 56px);
  .drawer {
    ::v-deep .el-drawer {
      width: 550px !important;
    }
    ::v-deep .el-drawer__header {
      margin-bottom: 0;
      padding: 14px 14px 14px 20px;
      color: #323232;
      font-size: 16px;
    }
    .content {
      border-top: 1px solid #f2f2f2;
      padding: 20px 20px 0;
      .groupList {
        height: calc(100vh - 220px);
        overflow-y: auto;
        padding-bottom: 10px;
      }
      .add {
        margin-top: 10px;
      }
      .group {
        border: 1px solid #eee;
        .header {
          padding: 8px;
          background: #eeeeee;
          color: #111f2c;
          span {
            font-size: 14px;
          }
          .el-icon-delete {
            float: right;
            cursor: pointer;
          }
        }
        .condition {
          padding: 10px;
          padding-right: 0;
          .list {
            .item {
              padding-bottom: 10px;
              display: flex;
              align-items: center;
              position: relative;
              .name {
                width: 150px;
              }
              .type {
                width: 100px;
              }
              .value {
                padding-left: 10px;
              }
              .value.betweenness {
                ::v-deep .el-input {
                  width: 100px;
                }
              }
              .delete {
                position: absolute;
                right: 5px;
                i {
                  cursor: pointer;
                }
              }
            }
          }
          .btn {
            padding-top: 10px;
            font-size: 12px;
            color: rgba(25, 31, 37, 0.56);
          }
        }
      }
      .divider {
        padding: 10px 0;
        color: #111f2c;
      }
      .tip {
        margin: 20px 0;
        width: 510px;
        text-indent: 17px;
        line-height: 45px;
        background: #f1f9ff;
        border: 1px solid #40a3f7;
        color: #46a6fe;
        font-size: 14px;
      }
    }
    .footer {
      position: absolute;
      bottom: 0;
      width: 100%;
      right: 0;
      text-align: right;
      height: 60px;
      line-height: 60px;
      padding-right: 20px;
      border-top: 1px solid #f2f2f2;
    }
  }
  ::v-deep .el-checkbox {
    border-right: 0;
  }
  .approve {
    padding: 0 20px;
    border-top: 1px solid #f2f2f2;
    .modelType {
      padding-top: 20px;
      .modelType-title {
        font-family: PingFangSC-Medium;
        font-size: 14px;
        color: #191f25;
        margin-bottom: 12px;
      }
      .modelType-content {
        .shu {
          ::v-deep .el-radio {
            display: block;
            margin: 10px 0;
          }
        }
        .userlist {
          border: 1px solid #f5f5f5;
          border-radius: 5px;
          padding: 5px;
        }
      }
    }
  }
  .zoom {
    display: flex;
    position: fixed;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    -webkit-box-pack: justify;
    -ms-flex-pack: justify;
    justify-content: space-between;
    height: 40px;
    width: 125px;
    right: 40px;
    margin-top: 30px;
    z-index: 10;
  }
  .zoom .zoom-in,
  .zoom .zoom-out {
    width: 30px;
    height: 30px;
    background: #fff;
    color: #c1c1cd;
    cursor: pointer;
    background-size: 100%;
    background-repeat: no-repeat;
  }

  .zoom .zoom-out {
    background-image: url("./assets/jian.png");
  }

  .zoom .zoom-out.disabled {
    opacity: 0.5;
  }

  .zoom .zoom-in {
    background-image: url("./assets/jia.png");
  }

  .zoom .zoom-in.disabled {
    opacity: 0.5;
  }
  .panl {
    transform: scale(1);
    display: inline-block;
    position: relative;
    width: 100%;
    padding: 54.5px 0;
    -webkit-box-align: start;
    -ms-flex-align: start;
    align-items: flex-start;
    -webkit-box-pack: center;
    -ms-flex-pack: center;
    justify-content: center;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
    min-width: -webkit-min-content;
    min-width: -moz-min-content;
    min-width: min-content;
    background-color: #f5f5f7;
    transform-origin: 50% 0px 0px;
  }

  .end-node {
    padding-bottom: 100px;
    border-radius: 50%;
    font-size: 14px;
    color: rgba(25, 31, 37, 0.4);
    text-align: left;
    .end-node-circle {
      width: 10px;
      height: 10px;
      margin: auto;
      border-radius: 50%;
      background: #dbdcdc;
    }
    .end-node-text {
      margin-top: 5px;
      text-align: center;
    }
  }
}
</style>
